/* * This file is part of Sensorium. * * Sensorium is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Sensorium is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Sensorium. If not, see * <http://www.gnu.org/licenses/>. * * */ package at.univie.sensorium.extinterfaces; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; import java.io.StringWriter; import java.net.Socket; import java.net.UnknownHostException; import java.security.KeyManagementException; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.UnrecoverableKeyException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.List; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocket; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import org.apache.http.HttpResponse; import org.apache.http.HttpVersion; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpPost; import org.apache.http.conn.ClientConnectionManager; import org.apache.http.conn.scheme.PlainSocketFactory; import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.scheme.SchemeRegistry; import org.apache.http.conn.ssl.SSLSocketFactory; import org.apache.http.entity.mime.MultipartEntity; import org.apache.http.entity.mime.content.ContentBody; import org.apache.http.entity.mime.content.FileBody; import org.apache.http.entity.mime.content.StringBody; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; import org.apache.http.params.BasicHttpParams; import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpParams; import org.apache.http.params.HttpProtocolParams; import org.apache.http.protocol.HTTP; import android.os.AsyncTask; import android.util.Log; import android.webkit.URLUtil; import android.widget.Toast; import at.univie.sensorium.SensorRegistry; public class HTTPSUploader extends AsyncTask<List<File>, Void, String> { private String posturl; private String username; private String password; public HTTPSUploader(String posturl, String username, String password) { this.posturl = posturl; this.username = username; this.password = password; } @Override protected String doInBackground(List<File>... params) { String result = uploadFiles(params[0]); return "Sensorium: Upload finished with: " + result; } protected void onPostExecute(String result) { Toast.makeText(SensorRegistry.getInstance().getContext(), result, Toast.LENGTH_SHORT).show(); } @Override protected void onPreExecute() { super.onPreExecute(); Toast.makeText(SensorRegistry.getInstance().getContext(), "Sensorium: Starting log upload.", Toast.LENGTH_SHORT).show(); } private String uploadFiles(List<File> files) { String result = ""; try { if (URLUtil.isValidUrl(posturl)) { HttpClient httpclient = getNewHttpClient(); HttpPost httppost = new HttpPost(posturl); MultipartEntity mpEntity = new MultipartEntity(); // MultipartEntity mpEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE); mpEntity.addPart("username", new StringBody(username)); mpEntity.addPart("password", new StringBody(password)); for (File file : files) { Log.d(SensorRegistry.TAG, "preparing " + file.getName() + " for upload"); ContentBody cbFile = new FileBody(file, "application/json"); mpEntity.addPart(file.toString(), cbFile); } httppost.addHeader("username", username); httppost.addHeader("password", password); httppost.setEntity(mpEntity); HttpResponse response = httpclient.execute(httppost); String reply; InputStream in = response.getEntity().getContent(); StringBuilder sb = new StringBuilder(); try { int chr; while ((chr = in.read()) != -1) { sb.append((char) chr); } reply = sb.toString(); } finally { in.close(); } result = response.getStatusLine().toString(); Log.d(SensorRegistry.TAG, "Http upload completed with response: " + result + " " + reply); } else { result = "URL invalid"; Log.d(SensorRegistry.TAG, "Invalid http upload url, aborting."); } } catch (IllegalArgumentException e) { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); e.printStackTrace(pw); Log.d(SensorRegistry.TAG, sw.toString()); } catch (FileNotFoundException e) { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); e.printStackTrace(pw); Log.d(SensorRegistry.TAG, sw.toString()); } catch (ClientProtocolException e) { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); e.printStackTrace(pw); Log.d(SensorRegistry.TAG, sw.toString()); } catch (IOException e) { result = "upload failed due to timeout"; StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); e.printStackTrace(pw); Log.d(SensorRegistry.TAG, sw.toString()); } return result; } public HttpClient getNewHttpClient() { try { KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); trustStore.load(null, null); SSLSocketFactory sf = new MySSLSocketFactory(trustStore); sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); HttpParams params = new BasicHttpParams(); int timeout = 10 * 1000; HttpConnectionParams.setConnectionTimeout(params, timeout); HttpConnectionParams.setSoTimeout(params, timeout); HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); HttpProtocolParams.setContentCharset(params, HTTP.UTF_8); SchemeRegistry registry = new SchemeRegistry(); registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); registry.register(new Scheme("https", sf, 443)); ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry); return new DefaultHttpClient(ccm, params); } catch (Exception e) { return new DefaultHttpClient(); } } private class MySSLSocketFactory extends SSLSocketFactory { SSLContext sslContext = SSLContext.getInstance("TLS"); final String ENABLED_CIPHERS[] = { "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", "TLS_DHE_RSA_WITH_AES_128_CBC_SHA", "TLS_DHE_RSA_WITH_AES_256_CBC_SHA", "TLS_DHE_DSS_WITH_AES_128_CBC_SHA", "TLS_ECDHE_RSA_WITH_RC4_128_SHA", "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", "TLS_RSA_WITH_AES_128_CBC_SHA", "TLS_RSA_WITH_AES_256_CBC_SHA", "SSL_RSA_WITH_3DES_EDE_CBC_SHA", "SSL_RSA_WITH_RC4_128_SHA", "SSL_RSA_WITH_RC4_128_MD5", }; final String ENABLED_PROTOCOLS[] = { "TLSv1.2", "TLSv1.1", "TLSv1" }; public MySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException { super(truststore); TrustManager tm = new X509TrustManager() { public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { } public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { } public X509Certificate[] getAcceptedIssuers() { return null; } }; sslContext.init(null, new TrustManager[] { tm }, null); } @Override public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException { SSLSocket s = (SSLSocket) sslContext.getSocketFactory().createSocket(socket, host, port, autoClose); s.setEnabledProtocols(ENABLED_PROTOCOLS); s.setEnabledCipherSuites(ENABLED_CIPHERS); return s; } @Override public Socket createSocket() throws IOException { return sslContext.getSocketFactory().createSocket(); } } }